package com.mach.platform.api.service;

import com.mach.platform.api.domain.Message;
import com.mach.platform.api.domain.ReadMessage;
import com.mach.platform.api.repository.MessageRepo;
import com.mach.platform.api.repository.ReadMessageRepo;
import com.mach.platform.api.repository.TeamRepo;
import com.mach.platform.api.util.ImageUtil;
import com.mach.platform.api.util.TimeUtil;
import com.mach.platform.domain.PageVo;
import com.mach.platform.repository.IotDevRepo;
import com.mach.platform.repository.IotSpaceRepo;
import com.mach.platform.utils.DateUtil;
import com.mach.platform.utils.springdata.Collections3;
import com.mach.platform.utils.springdata.DynamicSpecifications;
import com.mach.platform.utils.springdata.SearchFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.*;

/**
 * 消息业务处理
 */

@Service
public class MessageServiceImpl {

    @Autowired
    private MessageRepo messageRepo;

    @Autowired
    private TeamRepo teamRepo;

    @Autowired
    private IotDevRepo iotDevRepo;

    @Autowired
    private IotSpaceRepo iotSpaceRepo;

    @Autowired
    private ReadMessageRepo readMessageRepo;

    /**
     * 发送文字消息
     * @param message 消息数据
     * @return
     */
    public void saveMessage(Message message) throws UnsupportedEncodingException {
        saveMessage(message, 1, null);
    }


    /**
     * 发送图片消息
     * @param request 请求数据
     * @param file 图片
     */
    public boolean sendImage(HttpServletRequest request, MultipartFile file) {
        Message message = new Message();
        message.setHurdles(Integer.parseInt(request.getParameter("hurdles")));
        String openId = request.getHeader("openId");
        message.setSendOpenId(openId);
        message.setSendName(request.getParameter("sendName"));
        message.setDevId(Long.valueOf(request.getParameter("devId")));
        message.setDevName(request.getParameter("devName"));

        String imageSavePath = ImageUtil.getMessageImagePath("save");
        String imageShowPath = ImageUtil.getMessageImagePath("show");
        String md5FileName = DigestUtils.md5DigestAsHex((openId + System.currentTimeMillis()).getBytes());
        String imageName = md5FileName + ".jpg";
        File image = new File(imageSavePath + imageName);
        try {
            file.transferTo(image);
            saveMessage(message, 0, imageShowPath + imageName);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 保存消息数据
     * @param message 消息数据
     * @param isText 是否文本 1.是 0.否
     * @param imagePath 消息图片的路径
     */
    public void saveMessage(Message message, int isText, String imagePath) throws UnsupportedEncodingException {
        String createTime = DateUtil.getStringDate(new Date(), "yyyy-MM-dd HH:mm:ss");
        Long stationId = iotDevRepo.getById(message.getDevId()).getIotSpace().getId();
        String stationName = iotSpaceRepo.getById(stationId).getName();
        message.setCreateTime(createTime);
        message.setStationId(stationId);
        message.setStationName(stationName);
        message.setType(1);
        message.setIsText(isText);
        message.setIsDel(0);
        if (isText == 0) {
            message.setContent(imagePath);
        }
        messageRepo.save(message);
    }


    /**
     * 获取分页的消息列表
     * @param openId 用户openId
     * @param devId 设备id
     * @param hurdles 消息栏位
     * @param time 查询时间
     * @param pageable 分页参数
     * @return
     */
    public PageVo getMessageList(String openId, Long devId, Integer hurdles, String time, Pageable pageable) throws ParseException, UnsupportedEncodingException {
        Map params = new HashMap();
        params.put("isDel_eq", 0); // 未删除的消息
        params.put("type_eq", 1); // 目前只过滤设备的消息
        if (null != devId) {
            params.put("devId_eq", devId);
        }
        if (null != time) {
            params.put("createTime_plike", time);
        }
        if (hurdles != -1) { // 如果不是所有动态栏位
            if (hurdles == 0) {
                params.put("receiveOpenId_eq", openId);
            } else {
                params.put("hurdles_eq", hurdles);
            }
        }
        Specification specification = DynamicSpecifications.bySearchFilter(SearchFilter.parse(params).values(), Message.class);
        Page<Message> pageMessage = messageRepo.findAll(specification, pageable);
        if (pageMessage.getContent().size() == 0) {
            return PageVo.emptyPageVo(pageable.getPageNumber(), pageable.getPageSize());
        }
        // 查询消息的读取状态
        List<Long> messageIds = Collections3.extractToList(pageMessage.getContent(), "id");
        List<ReadMessage> readMessages = readMessageRepo.findByOpenIdMessageIds(openId, messageIds);
        List<Long> readMessageIds = Collections3.extractToList(readMessages, "messageId");

        // 组装消息数据
        List<Map> resultList = new ArrayList<>();
        Map resMessage;
        for (Message message : pageMessage.getContent()) {
            resMessage = new HashMap();
            String avatarPath = ImageUtil.getAvatarShowPath(message.getSendOpenId());
            resMessage.put("id", message.getId());
            resMessage.put("sendOpenId", message.getSendOpenId());
            if (hurdles == -1 || hurdles == 0) { // 所有动态，@我栏位需要返回头像地址
                resMessage.put("avatarPath", avatarPath);
            }
            resMessage.put("name", getMessageName(hurdles, message.getSendName()));
            resMessage.put("stationName", message.getStationName());
            resMessage.put("devId", message.getDevId());
            resMessage.put("devName", message.getDevName());
            resMessage.put("content", message.getContent());
            String showTime = TimeUtil.getFormatTime(message.getCreateTime());
            resMessage.put("showTime", showTime);
            resMessage.put("read", 0); // 默认未读
            resMessage.put("isText", message.getIsText()); // 是否文本
            if (readMessageIds.contains(message.getId())) {
                resMessage.put("read", 1);
            }
            resultList.add(resMessage);
        }
        return new PageVo(pageMessage.getNumber(), pageMessage.getSize(), pageMessage.getTotalElements(), pageMessage.getTotalPages(), resultList);
    }


    /**
     * 通过消息栏位和标题获取消息名字
     * @param hurdles 消息栏位
     * @param name 消息标题
     * @return
     */
    public String getMessageName(Integer hurdles, String name) {
        if (hurdles == -1 || hurdles == 0) {
            return name;
        }
        String messageName = "知能助手";
        if (hurdles == 4) {
            return "账单助手";
        }
        return messageName;
    }


    /**
     * 获取用户所有站房下有关的成员的信息
     * @param openId 用户openId
     * @return
     */
    public List<Map> getAllTeamMember(String openId) {
        List<Map> result = teamRepo.findAllTeamMember(openId);
        List<Map> mapList = new ArrayList<>();
        Map resultMap;
        for (Map map : result) {
            String avatarPath = ImageUtil.getAvatarShowPath((String) map.get("open_id"));
            resultMap = new HashMap();
            resultMap.put("openId", map.get("open_id"));
            resultMap.put("nickName", map.get("nick_name"));
            resultMap.put("avatarPath", avatarPath);
            mapList.add(resultMap);
        }
        return mapList;
    }


    /**
     * 已读消息
     * @param messageId 消息id
     * @return
     */
    public void readMessage(String openId, Long messageId) {
        ReadMessage readMessage = new ReadMessage(openId, messageId);
        readMessageRepo.save(readMessage);
    }


    /**
     * 删除消息，数据库标识删除
     * @param id 消息id
     * @return
     */
    public int deleteMessage(Long id) {
        return messageRepo.updateById(id);
    }


    public String info(Long id) {
        return null;
    }

}
